package com.gitee.feizns.quickstart.domain.tree;

import com.gitee.feizns.dynamic.reflect.Constructors;
import com.gitee.feizns.dynamic.tree.Node;
import com.gitee.feizns.dynamic.tree.NodeVo;
import com.gitee.feizns.dynamic.tree.Trees;
import com.gitee.feizns.quickstart.domain.Id;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 树
 * @author feizns
 * @since 2025/9/21
 */
public interface TreeNode<T extends TreeNode<T, ID>, ID> extends Id<ID> {

    /**
     * 根编号
     * @return {@link ID }
     */
    default ID rootId() {
        return null;
    }

    /**
     * 获取父编号
     * @return {@link ID }
     */
    ID getParentId();

    /**
     * 是否是根
     * @return boolean
     */
    default boolean isRoot() {
        return Objects.equals(rootId(), getParentId());
    }

    /**
     * 父节点
     * @return {@link T }
     */
    T parent();

    /**
     * 根
     * @return {@link T }
     */
    default T root() {
        @SuppressWarnings("unchecked")
        T result = (T) this;
        while ( !result.isRoot() ) {
            result = result.parent();
        }
        return result;
    }

    /**
     * 子项列表
     * @return {@link List }<{@link T }>
     */
    List<T> children();

    /**
     * 是否有子项
     * @return boolean
     */
    default boolean hasChildren() {
        List<T> children = children();
        return children != null && !children.isEmpty();
    }

    /**
     * 子编号列表
     * @return {@link List }<{@link Long }>
     */
    default List<ID> subIdList() {
        return children().stream().map(TreeNode::getId).collect(Collectors.toList());
    }

    /**
     * 遍历
     * @param consumer 消费者
     */
    default void each(Consumer<T> consumer) {
        //noinspection unchecked
        Trees.each((T) this, T::children, consumer);
    }

    /**
     * 获取当前节点及其所有子节点
     * @return {@link Node }<{@link T }, {@link ID }>
     */
    default List<T> descendants() {
        List<T> nodes = new ArrayList<>();
        each(nodes::add);
        return nodes;
    }

    /**
     * 复制当前节点及其子节点
     * @see NodeVo
     * @return {@link U }
     */
    default <U extends NodeVo<U, ID>> U duplicate() {
        List<T> descendants = descendants();
        List<U> build = build(descendants);
        return build != null && !build.isEmpty() ? build.get(0) : null;
    }

    /**
     * 复制当前节点及其子节点
     * @see NodeVo
     * @param nodeClass 节点类
     * @return {@link U }
     */
    default <U extends NodeVo<U, ID>> U duplicate(Class<U> nodeClass) {
        List<T> descendants = descendants();
        List<U> build = build(descendants, nodeClass);
        return build != null && !build.isEmpty() ? build.get(0) : null;
    }

    /**
     * 建
     * @param nodes 节点
     * @return {@link List }<{@link U }>
     */
    static <T extends TreeNode<T, ID>, U extends Node<U, ID>, ID> List<U> build(List<T> nodes) {
        return Trees.build(nodes.stream().map(node -> {
            //noinspection unchecked,rawtypes
            return (U) new NodeVo(node.getId(), node.getParentId());
        }).collect(Collectors.toList()));
    }

    /**
     * 构建树
     * @param nodes 节点
     * @param nodeClass 节点类型
     * @return {@link List }<{@link U }>
     */
    static <T extends TreeNode<T, ID>, U extends NodeVo<U, ID>, ID> List<U> build(List<T> nodes, Class<U> nodeClass) {
        return build(nodes, node -> {
            U instance = Constructors.newInstance(nodeClass);
            instance.setId(node.getId());
            instance.setParentId(node.getParentId());
            return instance;
        });
    }

    /**
     * 构建树
     * @param nodes 节点
     * @return {@link List }<{@link T }>
     */
    static <T extends TreeNode<T, ID>, U extends Node<U, ID>, ID> List<U> build(List<T> nodes, Function<T, U> nodeMapper) {
        return Trees.build(nodes.stream().map(nodeMapper).collect(Collectors.toList()));
    }

}
